/**
 * @file can.c
 * @author ait_zhengchunyu (ait_zhengchunyu@163.com)
 * @brief 
 * @version 0.1
 * @date 2022-02-08
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include "can.h"
#include "../dbg/dbg.h"


static struct can_dev_t can_device;
/**
 * @brief 当can 接收完成 更新标志
 * 
 * @param dev  can 
 * @return uint8_t 1 接收完成 0 未完成
 */
static uint8_t can_rx_finish(struct can_dev_t *dev)
{
    if(dev->rx_flag)
    {
        dev->rx_flag = 0;
			
			   dev->running_flag += 1;
        if(dev->running_flag>CAN_TIMEOUT_VALUE)dev->running_flag=CAN_TIMEOUT_VALUE;
        return 1;
    }
    else
    {
        return 0;
    }

}
/**
 * @brief can 发送数据函数
 * 
 * @param dev 
 * @param buf 
 * @param len 
 * @return int 
 */
static int can_transmit_message(struct can_dev_t *dev,uint8_t *buf,uint8_t len)
{
     if(can_send_msg(dev->obj.tx_id,dev->obj.ide,dev->obj.rtr,buf,len)==0)
        return 0;
    else 
        return -1;
}
/**
 * @brief 接收数据函数
 * 
 * @param dev 
 * @return int 
 */
static int can_receive_message(struct can_dev_t *dev)
{
   if(can_receive_msg(&(dev->obj.rx_id),&(dev->obj.ide),&(dev->obj.rtr),dev->obj.RX)==0)
   {
       dev->rx_flag = 1;
       return 0;
   }
   else
   {
       return -1;
   }

}
/**
 * @brief Set the ide object标准/扩展帧 
 * 
 * @param dev 
 * @param val val = 0 标准帧 1 扩展帧
 * @return int 
 */
static int can_set_ide(struct can_dev_t *dev,uint8_t val)
{
    if(dev==NULL)
    return -1;
    if (val>1)
    return -2;
    dev->obj.ide = val;
    return 0;
}   
/**
 * @brief Set the rtr 
 * 
 * @param dev 
 * @param val  0,数据帧;1,遥控帧 
 * @return int 
 */
static int can_set_rtr(struct can_dev_t *dev,uint8_t val)
{
    if(dev==NULL)
    return -1;
    if (val>1)
    return -2;
    dev->obj.rtr = val;
    return 0;
}
/**
 * @brief 设置can 设备源地址
 * 
 * @param dev 
 * @param val 
 * @return int 
 */
static int can_set_src_addr(struct can_dev_t *dev,uint32_t val)
{
    dev->obj.slave_addr = val;
    return 0;
}
/**
 * @brief 设置can 设备目的地址
 * 
 * @param dev 
 * @param val 
 * @return int 
 */
static int can_set_dst_addr(struct can_dev_t *dev,uint32_t val)
{
    dev->obj.master_addr = val;
    return 0;
}
/**
 * @brief 清除标志为
 * 
 * @param dev 
 */
static void can_clear_running_callback(struct can_dev_t *dev)
{
          if(dev->running_flag>0)dev->running_flag-=1;
          else dev->running_flag = 0;
}
/**
 * @brief 检查can 运行态 
 * 
 * @param dev 
 * @return uint8_t 
 */
uint8_t can_check_running(struct can_dev_t *dev)
{
    /**
     * @brief 每隔5s 清除标志位
     * 
     */
    return dev->running_flag;
}
/*
 * @ 设置限制标志位， 0 ：均流标志， 1 限流标志
 */
static void can_set_limit_flag(struct can_dev_t *dev ,uint8_t bit_num,uint8_t val)
{
   if(dev==NULL)
   return;
   if(bit_num>7)return;
   if(val)
   {
     dev->limit_flag |=(1<<bit_num); 
   }
   else
   {
     dev->limit_flag &=~(1<<bit_num); 
   }
}
static uint8_t can_get_limit_flag(struct can_dev_t *dev)
{
   if(dev==NULL)
   return 0;
   return  dev->limit_flag;
}
static void can_clear_limit_flag(struct can_dev_t *dev)
{
   if(dev==NULL)
   return;
   dev->limit_flag = 0;
}
uint32_t canSlaveAddr;
int can_init(struct can_dev_t **dev)
{
	//	canSlaveAddr = 11;
    can_hal_init();
    can_device.obj.slave_addr     					= canSlaveAddr;
    can_device.obj.master_addr     					= CAN_MASTER_ADDR;
    can_device.obj.ide        						= 0 ;
    can_device.obj.rtr        						= 0 ;
    can_device.set_ide        						= can_set_ide;
    can_device.set_rtr        						= can_set_rtr;
    can_device.set_src_id						    = can_set_src_addr;
    can_device.set_dst_id     						= can_set_dst_addr;
    can_device.rx_finish      						= can_rx_finish;
    can_device.tx_msg_func    						= can_transmit_message;
    can_device.rx_msg_func    						= can_receive_message ;
    can_device.can_clear_running_callback =can_clear_running_callback;
    can_device.check_running = can_check_running;
    
    can_device.set_limit_flag=can_set_limit_flag;
    can_device.get_limit_flag=can_get_limit_flag;
    can_device.clear_limit_flag=can_clear_limit_flag;
    *dev = &can_device;
    can_device.initflag = 1;
		return 0;
}
struct can_dev_t * can_get_instance(void)
{
    return &can_device;
}


